// RugbyIntro.cpp : Defines the entry point for the application.
//

#include <stdlib.h>
#include <iostream>

#include "Renderer.h"
#include "Application.h"
#include "FileOps.h"
#include "math.h"
#include "Utils.h"
#include "Color.h"

#include "RugbyIntro.h"

#include "rapidxml.hpp"

using namespace std;

// Renderer initialized in main file
extern Renderer *g_renderer;


// Constants
const float			FOG_DISTANCE = 50;

const int			NUM_POINTS = 10000;
const float			POINT_BOUNDARY = 150;
const int			NUM_POINT_SIZES = 4;

const int			NUM_CAMERATRACK_SEGMENTS = 50;

const int			MAX_MAP_TEXTURES = 9;

const float			BG_COLOR[] = {0, 0, 0.05, 1};

//
// @brief	Main entry
//
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	AppConfig config;
	config.appName = "Rugby Intro";
	config.cmdShow = nCmdShow;
	config.height = 700;
	config.width = 1200;
	config.hInstance = hInstance;
	
	RugbyIntro viewer;
	config.scene = &viewer;

	return Application::GetInstance()->Process( config );
}


RugbyIntro::RugbyIntro()
: m_star_points(NULL)
{
}

RugbyIntro::~RugbyIntro()
{
}


bool RugbyIntro::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam )
{
	bool handled = true;

	switch( msg )
	{
	case WM_KEYDOWN:
		switch( wParam )
		{	
			case VK_SPACE:
				m_camera.Reset();
				break;
			case 'A':
				m_animate_camera = !m_animate_camera;
				if ( m_animate_camera )
				{
					m_current_cam_anim_cmd = 0;
					m_current_cam_anim_cmd_num_exec = -1;
				}
				break;
			case 'C':
				m_cam_trace.clear();
				break;
			case 'F':
				glIsEnabled(GL_FOG) ? glDisable(GL_FOG) : glEnable(GL_FOG); 
				break;
			case 'P':
				m_render_stars = !m_render_stars;
				break;
			default:
				handled = false;
				break;
		}
	default:
		handled = false;
		break;
	};

	if ( !handled )
		return Scene::HandleMessage( msg, wParam, lParam );

	return true;
}

bool RugbyIntro::Init()
{
	Scene::Init();


	int width = m_screen_width;
	int height = m_screen_height;

	// Setup render specific stuff
	{
		// Setup viewport and projection matrix
		glViewport( 0, 0, width, height );

		glMatrixMode( GL_PROJECTION );
		glLoadIdentity();
		m_camera.glPerspective( width, height );
		
		// Other OpenGL flags
		glEnable(GL_DEPTH_TEST);				// Depthtest
		glDepthFunc(GL_LESS);
		glEnable(GL_CULL_FACE);					// Cull face
		//glEnable(GL_BLEND);						// Blending
		//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glShadeModel(GL_SMOOTH);				// Shading
		
		// TODO : enable
		glEnable(GL_FOG);
		glFogf( GL_FOG_END, FOG_DISTANCE );
		glFogi( GL_FOG_MODE, GL_LINEAR);
		glFogfv( GL_FOG_COLOR, BG_COLOR );

		glEnable( GL_POINT_SMOOTH );

		glClear( GL_ACCUM_BUFFER_BIT );
	}


	// Setup lighting
	{
		// TODO : enable
		glEnable(GL_LIGHTING);

		float lightPos[]		= { 1.0f, 0.f, 0.f, 0.0f };
		float lightAmbient[]	= { 0.2f, 0.2f, 0.2f, 1.0f };
		float lightDiffuse[]	= { 1.0f, 1.0f, 0.0f, 10.0f };
		glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
		glEnable(GL_LIGHT0);


		//float lightPos2[]		= { -10.5f, 0.f, 0.f, 0.0f };
		//float lightAmbient2[]	= { 0.1f, 0.1f, 0.1f, 0.1f };
		//float lightDiffuse2[]	= { 0.1f, 0.1f, 0.1f, 0.1f };
		//glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient2);
		//glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse2);
		//glLightfv(GL_LIGHT1, GL_POSITION, lightPos2);
		//glEnable(GL_LIGHT1);

		// Setup material
		glEnable(GL_COLOR_MATERIAL);
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	}

	InitStars();
	InitPlanets();
	InitGases();
	InitMap();
	InitCamAnim();

	return true;
}

void RugbyIntro::UnInit()
{
	if ( m_star_points )	delete [] m_star_points;

	Scene::UnInit();

	for( std::vector<Sphere>::const_iterator planet = m_planets.begin(); planet != m_planets.end(); planet++ )
	{
		gluDeleteQuadric( planet->sphere );
	}

	//gluDeleteNurbsRenderer( mAtmosphere.nurbs );
	for( std::vector<Sphere>::const_iterator gas = m_gases.begin(); gas != m_gases.end(); gas++ )
	{
		gluDeleteQuadric( gas->sphere );
	}

	for( std::vector<Texture*>::const_iterator tex = m_textures.begin(); tex != m_textures.end(); tex++ )
	{
		delete (*tex);
	}
}

void RugbyIntro::Update()
{
	Scene::Update();
	
	UpdateMap();
	
	UpdateCamAnim();
}

void RugbyIntro::Render( Renderer* renderer )
{
	// Clear back buffer
	glClearColor( BG_COLOR[0], BG_COLOR[1], BG_COLOR[2], BG_COLOR[3] );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;

	// Setup view matrix
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	m_camera.glLookAt();

	RenderStars();

	// Do motion blur using Accum buffer for stars
	// TODO : enable
//	glAccum( GL_MULT, 0.3f );	// Multiply accum buffer content
//	glAccum( GL_ACCUM, 1.0f );	// Add current color buffer to accum buffer
//	glAccum( GL_RETURN, 1.0f );	// Transfer from accum to color buffer

	//DrawAxis();
	RenderPlanets();

	RenderCamTrace();


	// Draw transparent stuff
	glDepthMask(false);				// Depth buffer writing
	glDisable(GL_CULL_FACE);		// Cull face
	glEnable(GL_BLEND);				// Blending
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	RenderGases();
	RenderMap();

	glDepthMask(true);				// Depth buffer writing
	glEnable(GL_CULL_FACE);			// Cull face
	glDisable(GL_BLEND);			// Blending
}

void RugbyIntro::InitStars()
{
	m_star_points = new float[ NUM_POINTS * 3 ];
	
	// NOTE:
	//	float x = (((float)rand() / RAND_MAX) * POINT_BOUNDARY) - (POINT_BOUNDARY/2.0);
	//	float y = (((float)rand() / RAND_MAX) * POINT_BOUNDARY) - (POINT_BOUNDARY/2.0);
	float multiplier = POINT_BOUNDARY / RAND_MAX;
	float subtractor = POINT_BOUNDARY / 2.0f;


	for( int i=0; i < NUM_POINTS; i++ )
	{
		m_star_points[i*3] = rand() * multiplier - subtractor;
		m_star_points[i*3+1] = rand() * multiplier - subtractor;
		m_star_points[i*3+2] = rand() * multiplier - subtractor;
	}

	m_render_stars = true;
}

void RugbyIntro::RenderStars()
{
	if ( m_render_stars == false || m_star_points == NULL )
		return;

	glPushMatrix();
	glTranslatef( 0, 0, -50 );
	glColor3f( 1, 1, 1 );

	// Activate and specify pointer to vertex array
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, m_star_points);

	// Draw points
	for ( int i=0; i < NUM_POINT_SIZES; i++ )
	{
		glPointSize( i+1 );
		glDrawArrays( GL_POINTS, i * NUM_POINTS/NUM_POINT_SIZES, NUM_POINTS/NUM_POINT_SIZES );
	}

	// Deactivate vertex arrays after drawing
	glDisableClientState(GL_VERTEX_ARRAY);
	glPopMatrix();
}

void RugbyIntro::InitPlanets()
{
	// Textures from: http://www.planetaryvisions.com

	Sphere p;

	p.sphere = gluNewQuadric();
	gluQuadricNormals( p.sphere, GLU_SMOOTH);
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = new Texture();
	p.texture->Load( "textures/earth_night.bmp", IMAGE_BMP );
	p.radius = 2;
	p.position.set( 0, 1.3, -25.5 );
	p.rotation.Set( Vector3( 1, 0, 0 ), -90 );
	m_planets.push_back( p );
	m_textures.push_back( p.texture );

	p.sphere = gluNewQuadric();
	gluQuadricNormals( p.sphere, GLU_SMOOTH);
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = new Texture();
	p.texture->Load( "textures/moon.bmp", IMAGE_BMP );
	p.radius = 1;
	p.position.set( 7, 1, -31 );
	p.rotation.Set( Vector3( 1, 0, 0 ), -90 );
	m_planets.push_back( p );
	m_textures.push_back( p.texture );

	p.sphere = gluNewQuadric();
	gluQuadricNormals( p.sphere, GLU_SMOOTH);
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = new Texture();
	p.texture->Load( "textures/mars.bmp", IMAGE_BMP );
	p.radius = 2;
	p.position.set( 30, -3, -4 );
	p.rotation.Set( Vector3( 1, 0, 0 ), -90 );
	m_planets.push_back( p );
	m_textures.push_back( p.texture );

	p.sphere = gluNewQuadric();
	gluQuadricNormals( p.sphere, GLU_SMOOTH);
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = new Texture();
	p.texture->Load( "textures/venus.bmp", IMAGE_BMP );
	p.radius = 2;
	p.position.set( -30, -3, -5 );
	p.rotation.Set( Vector3( 1, 0, 0 ), -90 );
	m_planets.push_back( p );
	m_textures.push_back( p.texture );

	p.sphere = gluNewQuadric();
	gluQuadricNormals( p.sphere, GLU_SMOOTH);
	gluQuadricTexture( p.sphere, GL_TRUE ); 
	p.texture = new Texture();
	p.texture->Load( "textures/jupiter.bmp", IMAGE_BMP );
	p.radius = 5;
	p.position.set( -3, 3, 3 );
	p.rotation.Set( Vector3( 1, 0, 0 ), -90 );
	m_planets.push_back( p );
	m_textures.push_back( p.texture );

	m_render_planets = true;
}

void RugbyIntro::RenderPlanets()
{
	if ( !m_render_planets )
		return;

	for( std::vector<Sphere>::const_iterator planet = m_planets.begin(); planet != m_planets.end(); planet++ )
	{
		glPushMatrix();
		glTranslatef( planet->position.x, planet->position.y, planet->position.z );
		glRotatef( planet->rotation.w, planet->rotation.v.x, planet->rotation.v.y, planet->rotation.v.z );
		glColor3f(1,1,1);

		planet->texture->Bind();
		gluSphere( planet->sphere, planet->radius, 40, 40 );

		glPopMatrix();
	}

	glDisable( GL_TEXTURE_2D );
}

void RugbyIntro::InitMap()
{
	// Load textures
	for( int i=0; i < MAX_MAP_TEXTURES; i++ )
	{
		char texname[100];
		sprintf( texname, "textures/nz%s%d.png", (i < 10) ? "0" : "", i );
		Texture* tex = new Texture;
		tex->Load( texname, IMAGE_PNG );
		m_textures.push_back( tex );
		m_map.textures.push_back( tex );
	}
	m_map.current_texture = 0;

	// Create mesh
	float width = (float)m_map.textures[0]->GetWidth() / (float)m_map.textures[0]->GetHeight();
	float height = 1;
	m_map.mesh.m_vtx_positions.push_back( Vector3( -width, -height, 0 ) );
	m_map.mesh.m_vtx_positions.push_back( Vector3( -width,  height, 0 ) );
	m_map.mesh.m_vtx_positions.push_back( Vector3(  width,  height, 0 ) );
	m_map.mesh.m_vtx_positions.push_back( Vector3(  width, -height, 0 ) );
	m_map.mesh.m_vtx_texcoords.push_back( Vector2( 0, 1 ) );
	m_map.mesh.m_vtx_texcoords.push_back( Vector2( 0, 0 ) );
	m_map.mesh.m_vtx_texcoords.push_back( Vector2( 1, 0 ) );
	m_map.mesh.m_vtx_texcoords.push_back( Vector2( 1, 1 ) );
	m_map.mesh.m_polygon_mode = Mesh::POLYGON_MODE_QUAD;
	m_map.mesh.m_face_vtx_indices.push_back(0);
	m_map.mesh.m_face_vtx_indices.push_back(1);
	m_map.mesh.m_face_vtx_indices.push_back(2);
	m_map.mesh.m_face_vtx_indices.push_back(3);


	// Set vars
	m_map.position.set( 0, -0.5, -27 );
	m_map.rotation.Set( Vector3( 0, 1, 0 ), 170 );
	m_map.scale.set( 0.3, 0.3, 0.3 );
	m_map.state = Map::ON;
	m_map.max_fade_time = 100;
	m_map.curr_fade_time = 100;
	
	m_render_map = true;
}

void RugbyIntro::UpdateMap()
{
	if ( m_map.state == Map::OFF )
		return;

	m_map.current_texture = (m_map.current_texture+1 ) % MAX_MAP_TEXTURES;

	if ( m_map.state == Map::FADEIN )
	{
		m_map.curr_fade_time++;
		if ( m_map.curr_fade_time >= m_map.max_fade_time )
		{
			m_map.curr_fade_time = m_map.max_fade_time;
			m_map.state = Map::ON;
		}
	}
	else if ( m_map.state == Map::FADEOUT )
	{
		m_map.curr_fade_time--;
		if ( m_map.curr_fade_time <= 0 )
		{
			m_map.curr_fade_time = 0;
			m_map.state = Map::OFF;
		}
	}
}

void RugbyIntro::RenderMap()
{
	if ( !m_render_map )
		return;

	if ( m_map.state == Map::OFF )
		return;

	float opacity = m_map.curr_fade_time / m_map.max_fade_time;

	// Render mesh
	m_map.textures[ m_map.current_texture ]->Bind();
	glColor4f( 1,1,1, opacity );
	glTranslatef( m_map.position.x, m_map.position.y, m_map.position.z );
	glRotatef( m_map.rotation.w, m_map.rotation.v.x, m_map.rotation.v.y, m_map.rotation.v.z );
	glScalef( m_map.scale.x, m_map.scale.y, m_map.scale.z );
	m_map.mesh.Render();
}

void RugbyIntro::InitCamAnim()
{
	m_animate_camera = false;

	static int numzoom = 50, numpan = 50, numrotate = 50, numrotatezoom = 75;
	static float zoom_back = -1000.0f;
	static Vector2 pan_back( 3000, 0 );
	static float zoom = 2.0f;
	static Vector2 pan( 1, 0 );
	static Vector3 axis(0, 1, 0);
	static float angle = 0.01f;

	m_cam_anim.clear();
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ZOOM, 1, zoom_back ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::PAN, 1, pan_back.x, pan_back.y ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ZOOM, numzoom*5, zoom+1 ) );
	//m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::PAN, numpan, pan.x, pan.y ) );
	//m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE, numrotate, axis.x, axis.y, axis.z, angle ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom, 0, 1, 0, -0.004, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom, 0, 1, 0, -0.01, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom, 0, 1, 0, -0.008, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom*2, 0, 1, 0, 0.004, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom*2, 0, 1, 0, 0.015, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom, 0, 1, 0, 0.01, zoom ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_ZOOM, numrotatezoom*2, 0, 1, 0, 0.007, zoom/2 ) );
	m_cam_anim.push_back( CamAnimCmd( CamAnimCmd::ROTATE_AND_PAN, numrotatezoom*3, 0, 1, 0, 0.01, pan.x, pan.y ) );
	

	m_current_cam_anim_cmd = 0;
	m_current_cam_anim_cmd_num_exec = -1;
}

void RugbyIntro::UpdateCamAnim()
{
	if ( m_animate_camera )
	{
		m_cam_trace.push_back( m_camera.m_pos );

		// Move to next command
		m_current_cam_anim_cmd_num_exec++;
		if ( m_current_cam_anim_cmd_num_exec >= m_cam_anim[m_current_cam_anim_cmd].repeat )
		{
			m_current_cam_anim_cmd_num_exec = 0;
			m_current_cam_anim_cmd++;

			// Put some indicator in the trace
			m_cam_trace.push_back( m_camera.m_pos+Vector3(1,0,0) );
			m_cam_trace.push_back( m_camera.m_pos+Vector3(0,1,0) );
			m_cam_trace.push_back( m_camera.m_pos+Vector3(0,0,1) );

			if ( m_current_cam_anim_cmd >= m_cam_anim.size() )
			{
				m_current_cam_anim_cmd = 0;
				m_camera.Reset();
			}
		}

		// Execute command
		switch( m_cam_anim[m_current_cam_anim_cmd].cmd )
		{
		case CamAnimCmd::ZOOM:
			m_camera.Zoom( m_cam_anim[m_current_cam_anim_cmd].params[0] );
			break;
		case CamAnimCmd::PAN:
			m_camera.Pan( m_cam_anim[m_current_cam_anim_cmd].params[0], m_cam_anim[m_current_cam_anim_cmd].params[1] );
			break;
		case CamAnimCmd::ROTATE:
			m_camera.Rotate( Vector3( m_cam_anim[m_current_cam_anim_cmd].params[0], m_cam_anim[m_current_cam_anim_cmd].params[1], m_cam_anim[m_current_cam_anim_cmd].params[2] ),
							m_cam_anim[m_current_cam_anim_cmd].params[3] );
			break;
		case CamAnimCmd::ROTATE_AND_ZOOM:
			m_camera.Rotate( Vector3( m_cam_anim[m_current_cam_anim_cmd].params[0], m_cam_anim[m_current_cam_anim_cmd].params[1], m_cam_anim[m_current_cam_anim_cmd].params[2] ),
				m_cam_anim[m_current_cam_anim_cmd].params[3] );
			m_camera.Zoom( m_cam_anim[m_current_cam_anim_cmd].params[4] );
			break;
		case CamAnimCmd::ROTATE_AND_PAN:
			m_camera.Rotate( Vector3( m_cam_anim[m_current_cam_anim_cmd].params[0], m_cam_anim[m_current_cam_anim_cmd].params[1], m_cam_anim[m_current_cam_anim_cmd].params[2] ),
				m_cam_anim[m_current_cam_anim_cmd].params[3] );
			m_camera.Pan( m_cam_anim[m_current_cam_anim_cmd].params[4], m_cam_anim[m_current_cam_anim_cmd].params[5] );
			break;
		};
	}

	using namespace rapidxml;
	xml_document<> doc;    // character type defaults to char
	doc.parse<parse_no_string_terminators>("<note>		\
		<to name=\"asd\">Tove</to>			\
		<from>Jani</from>		\
		<heading>Reminder</heading>		\
		<body>Don't forget me this weekend!</body>		\
		</note>");    // 0 means default parse flags

	xml_node<> *node = doc.first_node();
	xml_node<> *node1 = node->first_node();
	xml_node<> *node2 = node1->first_node();
	xml_attribute<> *attr = node1->first_attribute();
	std::string val( node2->value(), node2->value_size() );
	std::string attrname( attr->name(), attr->name_size() );
	std::string attrval( attr->value(), attr->value_size() );
}

// Render camera trace
void RugbyIntro::RenderCamTrace()
{
	if ( !m_render_cam_trace )
		return;

	glColor3f( 1,1,1 );
	glBegin( GL_LINE_STRIP );
	for( std::vector<Vector3>::const_iterator iter = m_cam_trace.begin(); iter != m_cam_trace.end(); iter++ )
	{
		glVertex3f( (*iter).x, (*iter).y, (*iter).z );
	}
	glEnd();
}


void RugbyIntro::InitGases()
{
	Texture* tex = new Texture;
	tex->Load( "textures/gas1.png", IMAGE_PNG );
	m_textures.push_back( tex );

	Sphere p;
	p.sphere = gluNewQuadric();
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = tex;
	p.radius = 20;
	p.position.set( 3, 3, -3 );
	p.rotation.Set( Vector3( 1, 0, 0 ), 34 );
	m_gases.push_back( p );

	p.sphere = gluNewQuadric();
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = tex;
	p.radius = 20;
	p.position.set( 40, 16, -4 );
	p.rotation.Set( Vector3( 0, 1, 0 ), 102 );
	m_gases.push_back( p );

	p.sphere = gluNewQuadric();
	gluQuadricTexture( p.sphere, GL_TRUE );
	p.texture = tex;
	p.radius = 20;
	p.position.set( 30, 6, -50 );
	p.rotation.Set( Vector3( 0, 1, 1 ), 223 );
	m_gases.push_back( p );

	m_render_gas = true;
}

void RugbyIntro::RenderGases()
{
	if ( !m_render_gas )
		return;

	//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

	for( std::vector<Sphere>::const_iterator gas = m_gases.begin(); gas != m_gases.end(); gas++ )
	{
		glPushMatrix();
		glTranslatef( gas->position.x, gas->position.y, gas->position.z );
		glRotatef( gas->rotation.w, gas->rotation.v.x, gas->rotation.v.y, gas->rotation.v.z );
		glColor3f(1,1,1);

		gas->texture->Bind();
		gluSphere( gas->sphere, gas->radius, 40, 40 );

		glPopMatrix();
	}

	glDisable( GL_TEXTURE_2D );
}


// RENDER nurbs surface
/*
	GLfloat knots2[14] = {0.0, 0.0, 0.0, 0.0, 0.25, 0.25,0.25,0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0};
	float nctlpoints[10][10][3];
	int u, v;
	for (u = 0; u < (10); u++) {
		for (v = 0; v < (10); v++) {

			nctlpoints[u][v][0] = u/10.0f; //((GLfloat)u - 1.5);
			nctlpoints[u][v][1] = v/10.0f; //((GLfloat)v - 1.5);
			nctlpoints[u][v][2] = 0.0;
		}
	} 

	static 

	float ctlpoints[10][10][3];
	for (u = 0; u < (10); u++) {
		for (v = 0; v < (10); v++) {

			ctlpoints[u][v][0] = u*5;
			ctlpoints[u][v][1] = v*5;
			ctlpoints[u][v][2] = 0.0;

			//if ((u == 4 || u == 5) && (v == 4 || v == 5)) 
			if ( u%5 == 0 ) 
			{
				ctlpoints[u][v][2] = 1;
			}		
			else
			{
				ctlpoints[u][v][2] = 0.0;
			}


		}
	} 


	glPushMatrix();
	glTranslatef( 0,10,0 );
	//glScalef( 3,3,0 );
	glColor3f(1,1,1);

	//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	//m_planets[0].texture->Bind();
	mAtmosphere.texture->Bind();

	gluBeginSurface( mAtmosphere.nurbs );

	gluNurbsSurface( mAtmosphere.nurbs, 
		14, knots2,
		14, knots2,
		10 * 3,
		3,
		&nctlpoints[0][0][0], 
		4, 4,
		GL_MAP2_TEXTURE_COORD_2);

	gluNurbsSurface( mAtmosphere.nurbs, 
		14, knots2,
		14, knots2,
		10 * 3,
		3,
		&ctlpoints[0][0][0], 
		4, 4,
		GL_MAP2_NORMAL);

	gluNurbsSurface( mAtmosphere.nurbs, 
		14, knots2,
		14, knots2,
		10 * 3,
		3,
		&ctlpoints[0][0][0], 
		4, 4,
		GL_MAP2_VERTEX_3);

	gluEndSurface( mAtmosphere.nurbs );

	glPopMatrix();

	glDisable( GL_TEXTURE_2D );
*/
